﻿using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using LDM.Framework.Application;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;

namespace LDM.Framework;

public static class SwaggerManager
{
    private static readonly SwaggerDocOptions _options;
    static SwaggerManager()
    {
        _options = App.GetOptions<SwaggerDocOptions>("SwaggerDoc") ?? throw new ArgumentNullException("Swagger 文档配置选项不能为空");
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="setupAction"></param>
    public static void ConfigureSwaggerGen(SwaggerGenOptions options)
    {
        options.AddSecurityDefinition("Bearer", _options.OpenApiSecurityScheme);

        if (_options.OpenApiSecurityRequirement.Count > 0)
        {
            options.AddSecurityRequirement(_options.OpenApiSecurityRequirement);
        }

        var apiGroupType = App.ScanTypes.FirstOrDefault(p => typeof(ApiGroupInfo).IsAssignableFrom(p));
        if (apiGroupType != null)
        {
            var obj = Activator.CreateInstance(apiGroupType);
            if (obj != null)
            {
                typeof(ApiGroupInfo).GetMethod("SetOpenApiInfo")?.Invoke(obj, null);
                var apiGroupInfo = (obj as ApiGroupInfo)!;
                foreach (FieldInfo fileld in obj.GetType().GetFields())
                {
                    var name = fileld.GetValue(obj)?.ToString();

                    options.SwaggerDoc(fileld.GetValue(obj)?.ToString(), new OpenApiInfo
                    {
                        Version = apiGroupInfo.Version,
                        Title = $"{apiGroupInfo.Title}-{name}",
                        Description = apiGroupInfo.Description,
                        Contact = new OpenApiContact
                        {
                            Name = apiGroupInfo.Contact?.Name,
                            Email = apiGroupInfo.Contact?.Email,
                            Url = apiGroupInfo.Contact?.Url
                        },
                        License = new OpenApiLicense
                        {
                            Name = apiGroupInfo.License?.Name,
                            Url = apiGroupInfo.License?.Url
                        }
                    });
                }
            }
        }

        foreach (var item in _options.IncludeXmlComments)
        {
            options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, item), true);//显示控制器层注释
            options.OrderActionsBy(s => s.RelativePath);//对Action的名称进行排序
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="options"></param>
    public static void ConfigureUseSwaggerUI(SwaggerUIOptions options)
    {
        var apiGroupType = App.ScanTypes.FirstOrDefault(p => typeof(ApiGroupInfo).IsAssignableFrom(p));
        if (apiGroupType != null)
        {
            var obj = Activator.CreateInstance(apiGroupType);
            if (obj != null)
            {
                foreach (FieldInfo fileld in obj.GetType().GetFields())
                {
                    var name = fileld.GetValue(obj)?.ToString();
                    options.SwaggerEndpoint($"/swagger/{name}/swagger.json", name);
                }
            }
        }
    }
}
